home *** CD-ROM | disk | FTP | other *** search
/ Workbench Add-On / Workbench Add-On - Volume 1.iso / BBS-Archive / Comm / AmiTCP30b2.lha / src / appl / napsaterm / napsaprefs.c < prev    next >
C/C++ Source or Header  |  1994-05-19  |  17KB  |  747 lines

  1. RCS_ID_C="$Id: napsaprefs.c,v 3.9 1994/05/18 15:09:54 ppessi Exp $";
  2. /*
  3.  * napsaprefs.c --- preferences for napsaterm
  4.  *
  5.  * Author: ppessi <Pekka.Pessi@hut.fi>
  6.  *
  7.  * Copyright (c) 1993 Pekka Pessi
  8.  *
  9.  * Created      : Sun Nov  7 08:27:25 1993 ppessi
  10.  * Last modified: Wed May 18 18:08:55 1994 ppessi
  11.  *
  12.  * $Log: napsaprefs.c,v $
  13.  * Revision 3.9  1994/05/18  15:09:54  ppessi
  14.  * Changed default ctrl8bit tool type to ctrl8bit=no
  15.  *
  16.  * Revision 3.8  1994/05/14  12:49:00  ppessi
  17.  * Multicharacter options are now preceded with double hyphen.
  18.  * Added "Control Codes" (7/8 bit) entry into "Setup" menu.
  19.  *
  20.  * Revision 3.7  1994/05/11  12:53:42  ppessi
  21.  * Merged changes from Napsaterm 3.5 by R. Knop
  22.  *
  23.  * Revision 3.6  1994/02/25  16:08:03  ppessi
  24.  * Fixed a bug in the national setting (only Danish and US could be selected)
  25.  *
  26.  * Revision 3.5  1994/02/25  02:33:38  ppessi
  27.  * Added RCS ID
  28.  *
  29.  * Revision 3.4  1994/02/25  02:00:48  ppessi
  30.  * Reverted back to S:Napsaprefs preference file
  31.  *
  32.  * Revision 3.3  1994/01/16  18:21:15  ppessi
  33.  * No perrorparse() printouts
  34.  *
  35.  * Revision 3.2  94/01/08  08:54:52  ppessi
  36.  * Enabled switch tool types; added support to different program names
  37.  * 
  38.  * Revision 3.1  94/01/07  22:51:25  ppessi
  39.  * Version 3 beta
  40.  * 
  41.  * Revision 2.1  93/11/18  18:34:12  ppessi
  42.  * Changed menu format.
  43.  * 
  44.  * Revision 2.0  93/11/15  03:38:53  ppessi
  45.  * Version 2 initial revision
  46.  */
  47.  
  48.  
  49. #include <stdio.h>
  50. #include <stdlib.h>
  51. #include <string.h>
  52. #include <ctype.h>
  53. #include "nifty.h"
  54. #include "amiga.h"
  55. #include "napsaprefs.h"
  56. #include "display.h"
  57. #include "dispmacros.h"
  58. #include "wimp.h"
  59.  
  60. #include <workbench/workbench.h>
  61. #include <workbench/startup.h>
  62.  
  63. #if USE_PRAGMAS
  64. #include <proto/icon.h>
  65. #endif
  66. #if USE_INLINE
  67. #include <inline/icon.h>
  68. #endif
  69. #if USE_CLIB
  70. #include <clib/icon_protos.h>
  71. #endif
  72.  
  73. #define PREFSFILE \
  74. "AmiTCP:db/NapsaPrefs" NUL "s:NapsaPrefs" NUL "s:NiftyPrefs" NUL
  75.  
  76. /*
  77.  * Hosts to connect
  78.  */
  79. #define MAXHOSTS 63        /* you can specify only 63 hosts */
  80. int  hostc;
  81. char *hostarray[MAXHOSTS + 1];
  82.  
  83. static void addhost(char *newhost, void *dummy);
  84.  
  85. struct napsaprefs np;  
  86.  
  87. struct parsing {
  88.   char     p_type;
  89.   char     p_slen;        /* significant length */
  90.   ushort   p_offset;
  91.   union {
  92.     const char *pu_option;
  93.     const char *pu_values;
  94.     int       (*pu_func)(char *, void *);
  95.   } p;
  96.   char    *p_resource;
  97.   long     p_default;
  98. };
  99.  
  100. #define p_option p.pu_option
  101. #define p_values p.pu_values
  102. #define p_func   p.pu_func
  103.  
  104. #define T_END     0
  105. #define T_STRING  1
  106. #define T_FLAG    2        /* true/false */
  107. #define T_TOGGLE  3        /* option will toggle the default */
  108. #define T_NUMBER  4
  109. #define T_SPECIAL 5
  110. #define T_ENUM    6
  111.  
  112. #define OFFSET_OF(x) ((ushort)&((struct napsaprefs *)NULL)->x)
  113.  
  114. #define LPARSE(type, what, optnam, resource, default) \
  115. {type,2,OFFSET_OF(what),optnam,resource,(long)default}
  116.  
  117. #define PARSE(type, what, optnam, resource, default) \
  118. {type,sizeof(optnam)-1,OFFSET_OF(what),optnam,resource,(long)default}
  119.  
  120. #define PENUM(what, resource, values, default, len) \
  121. {T_ENUM,len,OFFSET_OF(what),values,resource,(long)default}
  122.  
  123. #define PRESET(type, what, resource, default) \
  124. {type,0,OFFSET_OF(what),NULL,resource,(long)default}
  125.  
  126. #define PSPECIAL(what, resource, function) \
  127. {T_SPECIAL, 0, OFFSET_OF(what), (void *)function, resource, 0}
  128.  
  129. #define NP_ADDR(offset) (void*)((char*)&np + offset)
  130.  
  131. extern char nation_names[];
  132.  
  133. static char national_names[] = 
  134.   "None" NUL "Multinational" NUL "National" NUL;
  135.  
  136. static char bell_names[] = 
  137.   "None" NUL "Visual" NUL "Audio" NUL "Both" NUL "Display" NUL;
  138.  
  139. static char cursor_names[] =
  140.   "Underlined" NUL "Block" NUL "Invisible" NUL;
  141.  
  142. static char sizing_names[] = 
  143.   "None" NUL "Column" NUL "Row" NUL;
  144.  
  145. static char emulation_names[] =
  146.   "vt102" NUL "vt52" NUL "h19" NUL;
  147.  
  148. static char mouse_names[] =
  149.   "Off" NUL "Down" NUL "Up" NUL "Both" NUL;
  150.  
  151. /* Added RKNOP 940328 */
  152. static char keypad_names[] =
  153.   "Numeric" NUL "Application" NUL;
  154. /* End added RKNOP */
  155.  
  156. static const struct parsing presets[] =
  157. {
  158.   PARSE(T_STRING, logname,  "l",   NULL, NULL),
  159.   PARSE(T_FLAG,   show_version, "V", NULL, 1),
  160.   PARSE(T_TOGGLE, wait_to_end,  "w", "WAITTOEND", 0),
  161.   
  162.   /* emulation mode */
  163.   PENUM(emulation, "EMULATION", emulation_names, EMU_VT102, 3), 
  164.   PARSE(T_FLAG, emulation, "-vt102", NULL, EMU_VT102), 
  165.   PARSE(T_FLAG, emulation, "-vt52",  NULL, EMU_VT52), 
  166.   PARSE(T_FLAG, emulation, "-h19",   NULL, EMU_H19),
  167.  
  168.   PENUM(national,  "NATIONAL", national_names, 0, 2),
  169.   /* Default is US (plain ASCII) */
  170.   PENUM(nation, "NATION", nation_names, 0, 2),
  171.   PSPECIAL(keymap, "KEYMAP", parsekeymap),
  172.   PSPECIAL(keymap, "KEYBOARD", parsekeymap),
  173. #if 0
  174.   PRESET(T_STRING, nation, "NATION", NULL),
  175.   PRESET(T_STRING, keymap, "KEYMAP", NULL),
  176.   PRESET(T_STRING, keymap, "KEYBOARD", NULL),
  177. #endif
  178.  
  179.   LPARSE(T_TOGGLE, slow,   "-slow",   NULL, 0),
  180.  
  181.   /*Added RKNOP 940328*/
  182.   /* Keypad mode */
  183.   PENUM(applkeypad, "KEYPAD", keypad_names, KEYP_NUMERIC, 2),
  184.   PARSE(T_FLAG, applkeypad, "-numeric", NULL, KEYP_NUMERIC),
  185.   PARSE(T_FLAG, applkeypad, "-application", NULL, KEYP_APPL),
  186.   /*end added RKNOP 940328*/
  187.  
  188.   /* Cursor style, see "dispmacros.h" */
  189.   PENUM(visual, "CURSOR", cursor_names, CUR_BLOCK, 1),
  190.   PARSE(T_FLAG, visual, "-ic",   NULL, 2),
  191.  
  192.   /* stripping */
  193.   PARSE(T_TOGGLE, pass8,   "7",  "PASS8",        1),
  194.   PRESET(T_FLAG,   altismeta, "ALTISMETA", 0),
  195.   PARSE(T_TOGGLE, invert,   "v",  "INVERSE", 0),
  196.  
  197.   PENUM(mouse, "MOUSE", mouse_names, 0, 0),
  198.   PRESET(T_FLAG,  backspace, "BACKSPACE2DELETE", 0),
  199.   PRESET(T_FLAG,  delete,    "DELETE2BACKSPACE", 0),
  200.   PRESET(T_FLAG,  ctrl8bit,  "CTRL8BIT", 0),
  201.   PRESET(T_FLAG,  blink,     "CURSORBLINK", 0),
  202.  
  203.   PARSE(T_STRING, device,   "d",  "DEVICE", "serial.device"),
  204.   PARSE(T_NUMBER, unit,     "u",  "UNIT", 0),
  205.   PARSE(T_NUMBER, dnetwork, "N",   NULL, 0),
  206.   PARSE(T_NUMBER, bps,      "B",  "LINESPEED", 38400),
  207.   LPARSE(T_FLAG,  shared, "-shared", NULL, 1),
  208.   LPARSE(T_FLAG,  stdio,  "-stdio",  NULL, 1),
  209.   /* The telnet server port */
  210.   PARSE(T_STRING, service,  "s",  "SERVICE", "telnet"),
  211.   /* LPARSE(T_FLAG,  telnet,  "telnet",  NULL, 1), */
  212.  
  213.   /* This won't change the prefs structure */
  214.   PSPECIAL(emulation, "HOST", addhost),
  215.   PARSE(T_STRING, remotename, "r", "REMOTENAME", NULL),
  216.   PRESET(T_STRING, remoteterm, "REMOTETYPE", NULL),
  217.  
  218.   /* bell type */
  219.   PENUM(bell_type, "BELL", bell_names, BELL_VISUAL, 1),
  220.  
  221.   PARSE(T_TOGGLE, col80, "-80", "FIXEDCOLUMNS", 0),
  222.  
  223.   /* sizing gadget */
  224.   PENUM(size_gadget, "SIZEGADGET", sizing_names, SIZE_COLUMN, 1),
  225.   PARSE(T_STRING, title,    "p",  "TITLE", NULL),
  226.   PARSE(T_STRING, geometry, "g",  "GEOMETRY", NULL),
  227.   PARSE(T_STRING, pubscname,"S",  "PUBSCREENNAME", NULL),
  228.   PARSE(T_STRING, basefont, "f",  "BASEFONT", DEFAULTFONTDEF),
  229.  
  230.   {T_END}
  231. };
  232.  
  233. /*
  234.  * show options 
  235.  */
  236. static void usage(void)
  237. {
  238. /*  puts(version); */
  239. /*  puts(copyright); */
  240.   PutStr("Usage: " PROGNAME " [-option ...]\n"
  241.      "Available " PROGNAME " options are:\n"
  242.      "  -V                 show version number & copyright notice\n"
  243.      "  --h19              emulate an h19 instead of a vt102 terminal\n"
  244.      "  --vt52             emulate a vt52 on startup\n"
  245.      "  --vt102            emulate a vt102 on startup (default emulation)\n"
  246.      "  -l <file>          write all output to a log file\n"
  247.      "  --slow             start up in slow mode\n"
  248.      "  --ic               start up with invisible cursor\n"
  249.      "  --numeric          use numeric keypad\n"
  250.      "  --application      use application keypad\n"
  251.      "  -w                 wait after program ends before closing window\n"
  252.      "  -d <devicename>    specify device to use (e.g. serial.device)\n"
  253.      "  -u <unit #>        specify unit number to use (see -d)\n"
  254.      "  -B <linespeed>     specify line speed to use\n"
  255.      "  --shared           open device in shared mode\n"
  256.      "  --stdio            take input from stardard input.\n"
  257.      "  -N <net>           specify DNet network number\n"
  258.      "  -s <service>       specify TCP service name\n"
  259.      "  -r <username>      specify remote user name to use\n"
  260.      "  -7                 strip 8th bit of character codes\n"
  261.      "  -S <screen>        specify public screen name\n"
  262.      "  --80                set to fixed 80 columns\n"
  263.      "  -f <font>/<size>   set the name and size of the default font\n"
  264.      "  -p <name>          set the program name\n"
  265.      "  -g <l>/<t>/<w>/<h> set up window geometry.");
  266.   exit(1);
  267. }
  268.  
  269. /*
  270.  * Set default values 
  271.  */
  272. static void preset(void)
  273. {
  274.   const struct parsing *p;
  275.  
  276.   hostc = 0;
  277.  
  278.   for (p = presets; p->p_type != T_END; p++) {
  279.     if (p->p_resource) {
  280.       void *what = NP_ADDR(p->p_offset);
  281.       switch (p->p_type) {
  282.       case T_STRING:
  283.       case T_NUMBER:
  284.     *(long*)what = p->p_default;
  285.     break;
  286.       case T_FLAG:
  287.       case T_TOGGLE:
  288.       case T_ENUM:
  289.     *(char*)what = p->p_default;
  290.     break;
  291.       }
  292.     }
  293.   }
  294. }
  295.  
  296. /*
  297.  * `secure' strdup that removes the LF
  298.  */
  299. static char *pstrdup(char *s)
  300. {
  301.   char *val;
  302.   int size = 0;
  303.  
  304.   while (s[size] && s[size] != '\n')
  305.     size++;
  306.  
  307.   val = malloc(size + 1);
  308.   if (!val) {
  309.     fatalError(MEMORY_ERROR_MSG);
  310.   }
  311.   memcpy(val, s, size);
  312.   val[size] = '\0';
  313.  
  314.   return val;
  315. }
  316.  
  317. /*
  318.  * Add a new host to hosts structure 
  319.  */
  320. static void addhost(char *newhost, void *dummy) 
  321. {
  322.   if (hostc < MAXHOSTS) {
  323.     hostarray[hostc++] = newhost;
  324.     while (*newhost) {
  325.       if (*newhost++ == '|') {
  326.     newhost[-1] = '\0';
  327.     if (hostc < MAXHOSTS) {
  328.       hostarray[hostc++] = newhost;
  329.     } else {
  330.       break; 
  331.     }
  332.       }
  333.     }
  334.   } else {
  335.     free(newhost);
  336.   }
  337. }
  338.  
  339. /* 
  340.  * Parse a preset entry from icon or from preset file
  341.  */
  342. static void parse_entry(const char *preset, char *value)
  343. {
  344.   const struct parsing *p;
  345.  
  346.   for (p = presets; p->p_type != T_END; p++) {
  347.     if (p->p_resource == NULL || strcmp(p->p_resource, preset))
  348.       continue;
  349.     switch (p->p_type) {
  350.  
  351.     case T_STRING:
  352.       *(char**)NP_ADDR(p->p_offset) = pstrdup(value);
  353.       break;
  354.  
  355.     case T_NUMBER:
  356.       if (StrToLong(value, (long*)NP_ADDR(p->p_offset)) <= 0) {
  357.     perrorparse("Expected number for option %s", p->p_resource);
  358.       }
  359.       break;
  360.  
  361.     case T_FLAG:
  362.     case T_TOGGLE:
  363.       if (*value == '0' || 
  364.       *value == 'n' || 
  365.       (*value == 'o' && value[1] == 'f') || 
  366.       *value == 'f')
  367.     *(char*)NP_ADDR(p->p_offset) = 0;
  368.       else 
  369.     if (*value == '\0' ||
  370.         *value == '1' || 
  371.         *value == 'y' ||
  372.         (*value == 'o' && value[1] == 'n') || 
  373.         *value == 't')
  374.       *(char*)NP_ADDR(p->p_offset) = 1;
  375.       break;
  376.  
  377.     case T_SPECIAL:
  378.       /* Call the special function */
  379.       p->p_func(pstrdup(value), NP_ADDR(p->p_offset));
  380.       break;
  381.  
  382.     case T_ENUM:
  383.       {
  384.     /*
  385.      * Find which token is given 
  386.      */
  387.     int e;
  388.     const char *t = p->p_values;
  389.     char *n = value;
  390.  
  391.     /* NUL-terminate */
  392.     while (*n && *n != '\n')
  393.       n++;
  394.     *n = '\0';
  395.  
  396.     for (e = 0; *t; e++) {
  397.       if (p->p_slen ? 
  398.           !Strnicmp(t, value, p->p_slen) : 
  399.           !Stricmp(t, value)) {
  400.         /* Found */
  401.         *(char*)NP_ADDR(p->p_offset) = e;
  402.         break;
  403.       }
  404.       while (*t++)
  405.         ;
  406.     }
  407.     if (!*t)
  408.       perrorparse("Illegal value %s for option %s", value, p->p_resource);
  409.       }
  410.       break;
  411.     }
  412.     break; /* for () */
  413.   }
  414.   if (p->p_type == T_END) {
  415.     perrorparse("Unknown option %s", preset);
  416.   }
  417. }
  418.  
  419. /*
  420.  * Parse preset file
  421.  */
  422. static void parsepreset(char *myname, char *filename)
  423. {
  424.   char *s, *preset, buf[256];
  425.   BPTR fh;
  426.  
  427.   while (*filename) {
  428.     if (fh = Open(filename, MODE_OLDFILE))
  429.       break;
  430.     filename += strlen(filename) + 1;
  431.   }
  432.   if (!*filename) 
  433.     return;
  434.  
  435.   buf[255] = '\0';
  436.  
  437.   while (FGets(fh, buf, sizeof(buf)-1)) {
  438.     /* Comment? */
  439.     if (!isalnum(buf[0])) 
  440.       continue;
  441.     for (preset = s = buf; *s; s++) {
  442.       if (*s == ':')
  443.     break;
  444.       else if (islower(*s)) 
  445.     *s += 'A' - 'a';
  446.       else if (*s == '.') {
  447.     preset = s + 1;
  448.     /* Is the program name correct? */
  449.     if (strncmp(myname, buf, s - buf))
  450.       goto not_for_me;
  451.       }
  452.     }
  453.     if (*s) {
  454.       *s++ = '\0';
  455.       while (isspace(*s)) 
  456.     s++;
  457.       parse_entry(preset, s);
  458.     }
  459.   not_for_me:
  460.     ;
  461.   }
  462.  
  463.   Close(fh);
  464.   return;
  465. }
  466.  
  467. char **parseargs(char **argv)
  468. {
  469.   char *cont;
  470.   const struct parsing *p;
  471.   char progname[128];
  472.  
  473.   strncpy(progname, FilePart(argv[0]), sizeof(progname));
  474.   for (cont = progname; *cont; cont++) {
  475.     if (islower(*cont))
  476.       *cont += 'A' - 'a';
  477.   }
  478.  
  479.   preset();
  480.   parsepreset(progname, PREFSFILE); 
  481.  
  482.   for (argv = argv + 1; *argv != NULL; argv++) {
  483.     if (**argv == '-') {
  484.       /* '-' ends options */
  485.       if ((*argv)[1] == '\0')
  486.     return argv + 1;
  487.       cont = *argv + 1;
  488.       for (p = presets; p->p_type != T_END; p++) {
  489.     if (p->p_type < T_SPECIAL && 
  490.         p->p_option && 
  491.         !strncmp(p->p_option, cont, p->p_slen)) {
  492.       void *what = NP_ADDR(p->p_offset);
  493.       switch (p->p_type) {
  494.       case T_STRING:
  495.       case T_NUMBER:
  496.         cont = *++cont ? cont : *(++argv);
  497.         if (!cont) usage();
  498.         if (p->p_type == T_NUMBER) 
  499.           StrToLong(cont, (long *)what);
  500.         else
  501.           *(char **)what = cont;
  502.         break;
  503.       case T_FLAG:
  504.         *(char *)what = p->p_default;
  505.         break;
  506.       case T_TOGGLE:
  507.         *(char *)what = !p->p_default;
  508.         break;
  509.       }
  510.       break;
  511.     }
  512.       }
  513.       /* Didn't found the option? */
  514.       if (p->p_type == T_END) usage();
  515.     } else {
  516.       break;
  517.     }
  518.   }
  519.  
  520.   return argv;
  521. }
  522.  
  523. /*
  524.  * Workbench setup
  525.  */
  526. static void parseicon(UBYTE *name)
  527. {
  528.   struct DiskObject *dobj;
  529.   char **toolarray;
  530.   char *s, buf[256];
  531.  
  532.   if (!name) 
  533.     return;
  534.  
  535.   if (dobj = GetDiskObjectNew(name)) {
  536.     for (toolarray = (char **)dobj->do_ToolTypes;
  537.      toolarray && *toolarray;
  538.      toolarray++) {
  539.       s = strncpy(buf, *toolarray, sizeof(buf));
  540.       buf[sizeof(buf) - 1] = '\0';
  541.       while (*s && *s != '=')
  542.     s++;
  543.       if (*s)
  544.     *s++ = '\0';
  545.       parse_entry(buf, s);
  546.     }
  547.  
  548.     /* Free the diskobject we got */
  549.     FreeDiskObject(dobj);
  550.   } else {
  551.     addhost(pstrdup(name), NULL);
  552.   }
  553. }
  554.  
  555. char **parsewbargs(struct WBStartup *argmsg)
  556. {
  557.   LONG i;
  558.   struct WBArg *wb_arg_list = argmsg->sm_ArgList;
  559.  
  560.   preset();
  561.  
  562.   for (i = 0; i < argmsg->sm_NumArgs; i++, wb_arg_list++) {
  563.     if (wb_arg_list->wa_Lock) {
  564.       /* change to the proper directory */
  565.       BPTR olddir = CurrentDir(wb_arg_list->wa_Lock) ;
  566.  
  567.       /* process the file */
  568.       parseicon(wb_arg_list->wa_Name);
  569.       /* change back to the original directory when done */
  570.       CurrentDir(olddir) ;
  571.     } else {
  572.       /* something that does not support locks */
  573.       parseicon(wb_arg_list->wa_Name);
  574.     }
  575.   }
  576.  
  577.   hostarray[hostc] = NULL;
  578.  
  579.   return hostarray;
  580. }
  581.  
  582. #include <stdarg.h>
  583.  
  584. #if 0
  585. /*
  586.  * Print parse error
  587.  */
  588. void perrorparse(char *fmt, ...)
  589. {
  590.   va_list va;
  591.  
  592.   va_start(va, fmt);
  593.   vfprintf(stderr,fmt, va);
  594.   va_end(va);
  595.   fputc('\n', stderr);
  596. }
  597. #else
  598. void perrorparse(char *fmt, ...)
  599. {
  600. }
  601. #endif
  602.  
  603. /*
  604.  * Setup menu items show their current value
  605.  */
  606. #define SETUP_ITEMS 15
  607.  
  608. struct setup_menu_item setup_items[SETUP_ITEMS + 1] = 
  609. {
  610.   {
  611.     OFFSET_OF(national), 3,
  612.     "National Mode",
  613.     national_names,
  614.     change_national
  615.   },
  616.   {
  617.     OFFSET_OF(nation), 8,
  618.     "Nation",
  619.     nation_names,
  620.     change_nation
  621.   },
  622.   {
  623.     OFFSET_OF(emulation), 3,
  624.     "Terminal Type",
  625.     emulation_names,
  626.     NULL
  627.   },    
  628.   {
  629.     OFFSET_OF(ctrl8bit), 2, 
  630.     "Control Codes",
  631.     "7 bit" NUL "8 bit" NUL,
  632.     NULL
  633.   },
  634.   {
  635.     OFFSET_OF(backspace), 2, 
  636.     "Backspace is sent as",
  637.     "Backspace" NUL "Delete" NUL,
  638.     NULL
  639.   },
  640.   {
  641.     OFFSET_OF(delete), 2, 
  642.     "Del is sent as",
  643.     "Delete" NUL "Backspace" NUL,
  644.     NULL
  645.   },
  646.   {
  647.     OFFSET_OF(altismeta), 2, 
  648.     "Left Alt key is ",
  649.     "Alt" NUL "Meta" NUL,
  650.     NULL
  651.   },
  652.   {
  653.     /* Added RKNOP 940328 */
  654.     OFFSET_OF(applkeypad), 2,
  655.     "Keypad",
  656.     "Numeric" NUL "Application" NUL,
  657.     NULL
  658.   },
  659.   {
  660.     OFFSET_OF(mouse), 4,
  661.     "Mouse Events",
  662.     mouse_names,
  663.     NULL
  664.   },
  665.   {
  666.     OFFSET_OF(visual), 3,
  667.     "Cursor",
  668.     cursor_names,
  669.     change_cursor
  670.   },
  671.   {
  672.     OFFSET_OF(col80), 2,
  673.     "Display Width",
  674.     "Variable" NUL "80 Columns"  NUL,
  675.     change_mode80
  676.   },
  677.   {
  678.     OFFSET_OF(slow), 2, 
  679.     "Display Speed",
  680.     "Fast" NUL "Slow" NUL,
  681.     NULL
  682.   },
  683.   {
  684.     OFFSET_OF(bell_type), 5, 
  685.     "Bell Type",
  686.     bell_names,
  687.     NULL
  688.   },
  689.   {
  690.     OFFSET_OF(invert), 2,
  691.     "Reverse",
  692.     NULL,
  693.     change_invert
  694.   },
  695. /* added RKNOP 940328 */
  696.   {
  697.     OFFSET_OF(ansi_LNM), 2,
  698.     "ansi_LNM",
  699.     NULL,
  700.     change_ansi_LNM
  701.   },
  702. /* end added RKNOP 940328 */
  703.   { 0 }
  704. };
  705.  
  706. int getsetup(unsigned int n)
  707. {
  708.   return ((UBYTE*)&np)[setup_items[n].offset];
  709. }
  710.  
  711. /*
  712.  * Change setup menu item n, return new value 
  713.  *
  714.  * If new value is illegal, won't call toggle function
  715.  */
  716. int changesetup(unsigned int n, int val)
  717. {
  718.   UBYTE *vp = ((UBYTE*)&np) + setup_items[n].offset;
  719.  
  720.   if (n >= SETUP_ITEMS)
  721.     return -1;
  722.  
  723.   if (val >= 0 && val < setup_items[n].choices && *vp != val) {
  724.     *vp = val;
  725.     if (setup_items[n].change_f)
  726.       setup_items[n].change_f(val);
  727.   }
  728.  
  729.   return *vp;
  730. }
  731.  
  732. #if 0
  733. int
  734. main(int argc, char **argv)
  735. {
  736.   char **argv2 = parseargs(argv + 1);
  737.  
  738.   printpresets();
  739.  
  740.   if (*argv2) {
  741.     puts(*argv2);
  742.   }
  743.  
  744.   return 0;
  745. }
  746. #endif
  747.